---
title: Headless
description: You can run OpenHands with a single command, without starting the web application. This makes it easy to
  write scripts and automate tasks with OpenHands.
---

This is different from [the CLI](./cli-mode), which is interactive, and better for active development.

## With Python

To run OpenHands in headless mode with Python:
1. Ensure you have followed the [Development setup instructions](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
2. Run the following command:
```bash
poetry run python -m openhands.core.main -t "write a bash script that prints hi"
```

You'll need to be sure to set your model, API key, and other settings via environment variables
[or the `config.toml` file](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml).

### Working with Repositories

You can specify a repository for OpenHands to work with using `--selected-repo` or the `SANDBOX_SELECTED_REPO` environment variable:

> **Note**: Currently, authentication tokens (GITHUB_TOKEN, GITLAB_TOKEN, or BITBUCKET_TOKEN) are required for all repository operations, including public repositories. This is a known limitation that may be addressed in future versions to allow tokenless access to public repositories.

```bash
# Using command-line argument
poetry run python -m openhands.core.main \
  --selected-repo "owner/repo-name" \
  -t "analyze the codebase and suggest improvements"

# Using environment variable
export SANDBOX_SELECTED_REPO="owner/repo-name"
poetry run python -m openhands.core.main -t "fix any linting issues"

# Authentication tokens are currently required for ALL repository operations (public and private)
# This includes GitHub, GitLab, and Bitbucket repositories
export GITHUB_TOKEN="your-token"  # or GITLAB_TOKEN, BITBUCKET_TOKEN
poetry run python -m openhands.core.main \
  --selected-repo "owner/repo-name" \
  -t "review the security implementation"

# Using task files instead of inline task
echo "Review the README and suggest improvements" > task.txt
poetry run python -m openhands.core.main -f task.txt --selected-repo "owner/repo"
```

## With Docker

Set environment variables and run the Docker command:

```bash
# Set required environment variables
export SANDBOX_VOLUMES="/path/to/workspace"  # See SANDBOX_VOLUMES docs for details
export LLM_MODEL="anthropic/claude-sonnet-4-20250514"
export LLM_API_KEY="your-api-key"
export SANDBOX_SELECTED_REPO="owner/repo-name"  # Optional: requires GITHUB_TOKEN
export GITHUB_TOKEN="your-token"  # Required for repository operations

# Run OpenHands
docker run -it \
    --pull=always \
    -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.47-nikolaik \
    -e SANDBOX_USER_ID=$(id -u) \
    -e SANDBOX_VOLUMES=$SANDBOX_VOLUMES \
    -e LLM_API_KEY=$LLM_API_KEY \
    -e LLM_MODEL=$LLM_MODEL \
    -e SANDBOX_SELECTED_REPO=$SANDBOX_SELECTED_REPO \
    -e GITHUB_TOKEN=$GITHUB_TOKEN \
    -e LOG_ALL_EVENTS=true \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v ~/.openhands:/.openhands \
    --add-host host.docker.internal:host-gateway \
    --name openhands-app-$(date +%Y%m%d%H%M%S) \
    docker.all-hands.dev/all-hands-ai/openhands:0.47 \
    python -m openhands.core.main -t "write a bash script that prints hi"
```

> **Note**: If you used OpenHands before version 0.44, run `mv ~/.openhands-state ~/.openhands` to migrate your conversation history.

The `-e SANDBOX_USER_ID=$(id -u)` is passed to the Docker command to ensure the sandbox user matches the host user’s

## Additional Options

Common command-line options:
- `-d "/path/to/workspace"` - Set working directory
- `-f task.txt` - Load task from file
- `-i 50` - Set max iterations
- `-b 10.0` - Set budget limit (USD)
- `--no-auto-continue` - Interactive mode

Run `poetry run python -m openhands.core.main --help` for all options, or use a [`config.toml` file](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml) for more flexibility.

Set `export LOG_ALL_EVENTS=true` to log all agent actions.